import 'package:async/async.dart';
import 'package:boss/common/common.dart';
import 'package:boss/http/api/api_helper.dart';
import 'package:boss/models/commodity.dart';
import 'package:boss/models/store_menu.dart';
import 'package:boss/ui/page/commodity/categories/modal/deleteCommodityAlert/delete_commodity_alert.dart';
import 'package:boss/ui/widget/loading/loading.dart';
import 'package:flutter/material.dart';
import 'package:hi_common/hi_common.dart';

enum BatchType {
  normal, //正常
  changeClassification, //改分类
  delete, //删除
}

class CommodityProvider extends ChangeNotifier {
  //菜品分类及菜品数据
  List<StoreMenu> storeMenus = [];

  //当前选中的菜品分类下表
  int storeMenuSelectIndex = 0;

  //当前所有的菜品列表
  List<Commodity> get commodities {
    List<Commodity> list = [];

    this.storeMenus.forEach((menu) {
      list.addAll(menu.commodityList);
    });

    return list;
  }

  //当前选中的菜品菜品列表
  List<Commodity> get currentCommodities {
    if (storeMenus.length == 0) {
      return [];
    }

    return storeMenus[storeMenuSelectIndex].commodityList ?? [];
  }

  //下架菜品
  List<Commodity> get offSaleCommodities {
    List<Commodity> list = [];
    this.storeMenus.forEach((menu) {
      list.addAll(menu.commodityList.where((element) => !element.isOnSale));
    });
    return list;
  }

  //沽清菜品
  List<Commodity> get outStockCommodities {
    List<Commodity> list = [];
    this.storeMenus.forEach((menu) {
      list.addAll(menu.commodityList.where((element) => element.stock == 0));
    });
    return list;
  }

  //套餐分类
  List<StoreMenu> get packageStoreMenus => storeMenus.where((item) => item.isPackages == 1).toList();

  //不包含套餐分类
  List<StoreMenu> get normalStoreMenus => storeMenus.where((item) => item.isPackages != 1).toList();

  int get allCommodityCount => commodities.length;

  //当前选中的分类
  StoreMenu get currentMenuCategory {
    if (storeMenus.length == 0) return null;

    return storeMenus[storeMenuSelectIndex];
  }

  //操作类型
  BatchType batchType = BatchType.normal;

  //是否可以取消批量操作
  bool get isCancelBatch => batchType == BatchType.changeClassification || batchType == BatchType.delete;

  //选中的菜品
  List<Commodity> get selectedCommodities => commodities.where((commodity) => commodity.isSelected).toList();

  //设置菜品分类
  setStoreMenus(List<StoreMenu> storeMenus) {
    this.storeMenus = storeMenus;

    notifyListeners();
  }

  //设置菜品选中下标
  setStoreMenuSelectIndex(int index) {
    storeMenuSelectIndex = index;
    notifyListeners();
  }

  //添加菜品分类
  Future<bool> addStoreMenu(StoreMenu menu) async {
    try {
      var menuName = StringUtil.trim(menu.menuName ?? '');
      var materialIds = menu.commodityMeterialList.map((item) => item.id.toString()).toList();
      if (menuName == '') {
        toast('请输入分类名称');
        return false;
      }

      showLoadingToast();

      var res = await addMenuCategory(
        name: menuName,
        meterialIdList: materialIds,
        isPackages: menu.isPackages,
      );
      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      var newMenu = StoreMenu.fromJson(res.data['menuCategory']);
      storeMenus.add(newMenu);
      notifyListeners();

      toast('新增成功');

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //修改菜品分类
  Future<bool> updateStoreMenu(StoreMenu menu) async {
    try {
      var menuName = StringUtil.trim(menu.menuName ?? '');
      if (menuName == '') {
        toast('请输入分类名称');
        return false;
      }

      showLoadingToast();

      var res = await updateMenuCategory(data: menu);
      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      var index = storeMenus.indexWhere((item) => item.menuId == menu.menuId);
      if (index == -1) {
        toast('分类未找到');
        return false;
      }

      storeMenus[index] = menu;
      notifyListeners();

      toast('修改成功');

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //删除菜品分类
  Future<bool> deleteStoreMenu(StoreMenu menu) async {
    try {
      showLoadingToast();

      var res = await deleteMenuCategory(menu.menuId);
      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      storeMenus.removeWhere((item) => item.menuId == menu.menuId);
      if (storeMenuSelectIndex == storeMenus.length && storeMenuSelectIndex != 0) {
        storeMenuSelectIndex = storeMenus.length - 1;
      }

      notifyListeners();

      toast('删除成功');

      return true;
    } catch (e) {
      toast(Constant.httpServeErrText);
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //重置
  reset({bool isNotifyListeners = false}) {
    storeMenus = [];
    storeMenuSelectIndex = 0;
    batchType = BatchType.normal;

    if (isNotifyListeners) notifyListeners();
  }

  //获取数据
  Future<Result<List<StoreMenu>>> initData({List<Commodity> selectedCommoditys, bool isShowPackage = true, List<int> filterType}) async {
    try {
      var res = await queryMenuCategory();
      if (!res.successful()) {
        return Result.error(Constant.httpErrText);
      }

      setStoreMenus(res.data);
      return Result.value(res.data);
    } catch (e) {
      return Result.error(Constant.httpErrText);
    } finally {}
  }

  //切换菜品ui状态
  setCommodityStatus(BatchType type) {
    batchType = type;
    notifyListeners();
  }

  //切换菜品选中状态
  toggleCommoditySelected(Commodity commodity) {
    if (batchType == BatchType.changeClassification && selectedCommodities.any((item) => item.commodityType != commodity.commodityType)) {
      toast('套餐和普通菜品无法同时选择');
      return;
    }

    commodity.isSelected = !commodity.isSelected;
    notifyListeners();
  }

  //批量操作
  setBatchType(BatchType type) {
    batchType = type;
    storeMenus.forEach((menu) {
      menu.commodityList.forEach((commodity) {
        commodity.isSelected = false;
      });
    });
    notifyListeners();
  }

  //删除菜品
  Future<bool> deleteCommodityByBean(Commodity data) async {
    try {
      showLoadingToast();
      var res = await deleteCommodity(data.id);
      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('删除成功');

      for (final menu in storeMenus) {
        menu.commodityList.removeWhere((item) => item.id == data.id);
        final commodities = menu.commodityList.iterator;
        while (commodities.moveNext()) {
          final commodity = commodities.current;

          if (commodity.id == data.id) {
            menu.commodityList.remove(commodity);
          }

          if (commodity.isPackageCommodity) {
            bool flag = commodity.mustCommodityList.any((element) => element.commodityId == data.id);

            if (!flag) {
              flag = commodity.packagesGroupList.any((group) => group.commodityFormList.any((element) => element.commodityId == data.id));
            }

            if (flag) {
              commodity.onsale = 0;
            }
          }
        }
      }

      notifyListeners();
      return true;
    } catch (e) {
      toast(Constant.httpServeErrText);
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //批量删除菜品
  deleteCommoditysById() async {
    if (selectedCommodities.length == 0) {
      toast('请选择菜品');
      return;
    }

    deleteCommodityAlert(
      GlobalPageContext.instance.context,
      onConfirm: (context) async {
        Navigator.pop(context);

        try {
          showLoadingToast();
          var response = await batchDeleteCommodity(selectedCommodities.map((item) => item.id).toList());

          if (!response.successful()) {
            toast(response.msg);
            return false;
          }

          batchType = BatchType.normal;

          selectedCommodities.forEach((item) {
            storeMenus.forEach((menu) {
              if (menu.menuId == item.menuId) {
                menu.commodityList.remove(item);
              }
            });
          });
          notifyListeners();

          toast("批量删除成功");

          return true;
        } catch (e) {
          toast(e.toString());
          return false;
        } finally {
          hideLoadingToast();
        }
      },
    );
  }

  //菜品移动分类
  Future<bool> changeCommodityMenu(StoreMenu targetMenu) async {
    try {
      if (targetMenu == null) {
        toast('请选择分类');
        return false;
      }
      showLoadingToast();
      var result = await batchMoveCommodity(
        commodityIdList: selectedCommodities.map((item) => item.id).toList(),
        menuId: targetMenu.menuId,
      );
      if (!result.successful()) {
        toast(result.msg);
        return false;
      }

      var cloneSelectedCommodities = selectedCommodities.map((commodity) {
        var temp = Commodity.fromJson(commodity.toJson());
        temp.isSelected = false;
        temp.menuId = targetMenu.menuId;
        temp.menuName = targetMenu.menuName;

        return temp;
      }).toList();

      targetMenu.commodityList.addAll(cloneSelectedCommodities);

      storeMenus.forEach((menu) {
        menu.commodityList.removeWhere((commodity) => commodity.isSelected);
      });
      notifyListeners();

      toast('移入成功');

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //添加菜品
  Future<bool> saveCommodity(Commodity commodity, {StoreMenu oldStoreMenu}) async {
    try {
      if (commodity.title == null || commodity.title == '') {
        toast('菜品名称不能为空！');
        return false;
      }

      if (commodity.menuId == null) {
        toast('菜品分类不能为空！');
        return false;
      }

      if (commodity.commoditySkuList.length == 0 && commodity.price == null) {
        toast('售卖价不能为空！');
        return false;
      }

      if (commodity.isChefPrint && commodity.printerInfoList?.length == 0) {
        toast('请选择后厨打印机');
        return false;
      }

      showLoadingToast();

      var isUpdate = commodity.id != null;

      var result = await (!isUpdate ? commodityAddNew(commodity) : updateCommodity(commodity));
      if (!result.successful()) {
        toast(result.msg);
        return false;
      }

      await initData();

      toast(isUpdate ? '修改成功' : '添加成功');

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //分类排序
  sortStoreMenus(List<StoreMenu> storeMenus) async {
    try {
      showLoadingToast();

      var result = await sortMenuCategory(storeMenus.map((item) => item.menuId).toList());

      if (!result.successful()) {
        toast(result.msg);
        return;
      }

      this.storeMenus = storeMenus;
      notifyListeners();
      toast('排序成功');

      Navigator.pop(GlobalPageContext.instance.context);
    } catch (e) {
      toast(e.toString());
    } finally {
      hideLoadingToast();
    }
  }

  //设置菜品数量
  setCommodityCount(Commodity commodity, int count) {
    commodity.count = count;
    commodity.isSelected = count > 0;
    notifyListeners();
  }

  //添加套餐
  Future<bool> plusPackage(Commodity commodity) async {
    try {
      if (!RegUtil.testNotEqEmpty(commodity.title)) {
        toast('请输入套餐名字');
        return false;
      }
      if (commodity.menuId == null) {
        toast('请选择套餐分类');
        return false;
      }
      if (commodity.price == null) {
        toast('请输入套餐价格');
        return false;
      }
      if (commodity.mustCommodityList.length == 0 && commodity.packagesGroupList.length == 0) {
        toast('菜品或套餐分组二者至少必填一项');
        return false;
      }

      showLoadingToast();

      bool isUpdate = commodity.id != null;

      var res = await (!isUpdate ? addPackage(commodity) : updatePackage(commodity));

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      await initData();
      toast(isUpdate ? '修改成功' : '添加成功');

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //删除套餐
  Future<bool> removePackage(int id) async {
    try {
      showLoadingToast();

      var res = await deletePackage(id);
      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      await initData();
      toast('删除成功');

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  void toggleSale(Commodity commodity) async {
    final copy = Commodity.fromJson(commodity.toJson());
    copy.onsale = copy.onsale == 0 ? 1 : 0;
    String okMsg = copy.isOnSale ? '上架成功' : '下架成功';

    try {
      showLoadingToast();
      final res = await updateCommodity(copy);
      if (!res.successful()) {
        toast(res.msg);
        return;
      }
      toast(okMsg);

      commodities.forEach((item) {
        if (item.id == copy.id) {
          item.onsale = copy.onsale;
        }
      });
      notifyListeners();
    } catch (e) {
      toast(e.toString());
    } finally {
      hideLoadingToast();
    }
  }

  Future<bool> updateStock(int id, String text) async {
    try {
      showLoadingToast();

      int stock;
      if (text == '无限') {
        stock = -1;
      } else {
        stock = int.parse(text);
      }

      final res = await updateCommodityStock(id, stock);
      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('菜品已沽清');

      commodities.firstWhere((element) => element.id == id, orElse: () => null)?.stock = stock;
      notifyListeners();

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }
}
